package com.pos.uniplugin_all.dhscale;

import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;



/**
 * @author ：liujl
 * @date ：Created 2023/8/26 09:34
 * @description：WebSocket工具类
 */
public class WebSocketUtil {

    /**
     * 电子秤端口号
     */
    private final static int PORT = 4001;

    /**
     * 指令发送成功
     */
    private final static String SEND_SUCCESS = "SEND_SUCCESS";

    /**
     * 指令发送失败
     */
    private final static String SEND_FAIL = "SEND_FAIL";

    /**
     * Socket实例
     */
    private Socket socket;

    /**
     * WebSocketUtil实例
     */
    private WebSocketUtil webSocketUtil;

    /**
     * 获取WebSocketUtil实例
     *
     * @return WebSocketUtil实例
     */
    public WebSocketUtil getWebSocketUtil() {
        if (webSocketUtil == null) {
            webSocketUtil = new WebSocketUtil();
        }
        return webSocketUtil;
    }

    /**
     * 连接大华电子秤
     *
     * @param ip 电子秤IP
     * @return 是否连接成功
     */
    public boolean connect(String ip,int port) {
        try {
            socket = new Socket();
            InetSocketAddress socketAddress = new InetSocketAddress(ip, port);
            socket.connect(socketAddress, 10 * 1000);
            socket.setSoTimeout(5 * 1000);
            return socket.isConnected();
        } catch (IOException e) {
            Log.e("wdx","======>>>>>>【 Socket通信连接异常！！！ 】<<<<<<======");
            throw new RuntimeException(e);
        }
    }

    /**
     * 设置大华电子秤商品
     * @param goods 商品信息
     * @return 是否设置成功
     */
    public boolean setGoods(BarCodeScaleGoods goods) {
        String plu = goods.getPluCode();
        String code = goods.getCode();
        // 价格单位为分，所以得乘以100
        String price = String.valueOf(new Double(goods.getPrice() * 100).intValue());
        String goodsName = DhScaleUtils.StringToAreaByteCode(goods.getGoodsName());
        String unit = goods.getUnit();
        // 因为发送商品数据的指令每个字段没有明确的标识位，大华在解析指令时是以下标来获取信息的，所以得保证每个字段的信息字节数是固定的，所以得对动态的信息进行补位
        while (plu.length() < 4) {
            plu = '0' + plu;
        }
        while (price.length() < 6) {
            price = '0' + price;
        }
        // PLU码（4位）+商品条码（7位）+商品价格（6位）+商品单位（1位）+商品名称（40位）
        String goodsInfo = String.format("!0V%sA%s%s%s00000099901010000000000000000000000000000000000000000000000B%sCDE", plu, code, price, unit, goodsName);
        byte[] bytes = goodsInfo.getBytes();
        String result = sendCommand(bytes);
        if (SEND_SUCCESS.equals(result)) {
            try {
                InputStreamReader ipr = new InputStreamReader(socket.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(ipr);
                String str = bufferedReader.readLine();
                if (str.length() > 0) {
                    return true;
                }
                return false;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }

    /**
     * 设置大华电子秤热键
     */
    public void setHotKey() {
        String str = "!0L00A";
        for (int i = 1; i <= 36; i++) {
            if (String.valueOf(i).length() == 1) {
                str += "000" + i;
            } else if (String.valueOf(i).length() == 2) {
                str += "00" + i;
            }
        }
        str += "B!0L01A";
        for (int i = 37; i <= 71; i++) {
            if (String.valueOf(i).length() == 1) {
                str += "000" + i;
            } else if (String.valueOf(i).length() == 2) {
                str += "00" + i;
            }
        }
        str += "B";
        byte[] bytes = str.getBytes();
        sendCommand(bytes);
    }


    /**
     * 清除大华秤内部商品数据
     *
     * @return 是否清除成功
     */
    public boolean clearData() {
        if (socket != null && socket.isConnected()) {
            byte[] bytes = {0x21, 0x30, 0x49, 0x41};
            sendCommand(bytes);
            byte[] bytes2 = {0x21, 0x30, 0x48, 0x41};
            sendCommand(bytes2);
            return true;
        }
        return false;
    }

    /**
     * 向大华电子秤发送指令
     *
     * @param bytes 指令
     * @return 是否发送成功
     */
    private String sendCommand(byte[] bytes) {
        byte[] suffix = {0x0d, 0x0a, 0x03};
        try {
            if (socket != null && socket.isConnected() && socket.getOutputStream() != null) {
                byte[] command = DhScaleUtils.byteMerger(bytes, suffix);
                socket.getOutputStream().write(command);
                Log.i("wdx","======>>>>>>【 指令发送成功！！！ 】<<<<<<======");
                return SEND_SUCCESS;
            }
        } catch (IOException e) {
            Log.e("wdx","======>>>>>>【 Socket未连接！！！ 】<<<<<<======");
            throw new RuntimeException(e);
        }
        Log.e("wdx","======>>>>>>【 指令发送失败！！！ 】<<<<<<======");
        return SEND_FAIL;
    }

    /**
     * 关闭Socket连接
     */
    public void closeConnect() {
        if (socket != null || socket.isConnected()) {
            Log.i("wdx","======>>>>>>【 Socket通信连接关闭！！！ 】<<<<<<======");
            try {
                if (socket != null) {
                    socket.close();
                    socket = null;
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                try {
                    if (socket != null) {
                        socket.close();
                        socket = null;
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static String main(String ip, String port) {
        String conncetStr = "";
        // 连接电子秤
        WebSocketUtil webSocketUtil = new WebSocketUtil().getWebSocketUtil();
        boolean connect = webSocketUtil.connect(ip, Integer.decode(port));//"192.168.2.107"
        conncetStr = connect ? "socket连接成功" : "socket连接失败";
        Log.d("wdx", connect ? "socket连接成功" : "socket连接失败");
//        System.out.println(connect ? "socket连接成功" : "socket连接失败");
//        Looper.prepare();
//        Toast.makeText(mainActivity, connect ? "socket连接成功" : "socket连接失败", Toast.LENGTH_SHORT).show();
        // 清除数据
//        boolean clearData = webSocketUtil.clearData();
//        System.out.println(clearData ? "清除数据成功" : "清除数据失败");

        // 设置商品
        BarCodeScaleGoods barCodeScaleGoods = new BarCodeScaleGoods();
        barCodeScaleGoods.setPluCode("0072");
        barCodeScaleGoods.setCode("2281080");
        barCodeScaleGoods.setPrice(10);
        barCodeScaleGoods.setGoodsName("我是商品名称飞飞飞");
        barCodeScaleGoods.setUnit("0");
        boolean setGoods = webSocketUtil.setGoods(barCodeScaleGoods);
        Log.d("wdx", setGoods ? "设置商品成功" : "设置商品失败");
//        Looper.prepare();
//        Toast.makeText(mainActivity, setGoods ? "设置商品成功" : "设置商品失败", Toast.LENGTH_SHORT).show();
//        System.out.println(setGoods ? "设置商品成功" : "设置商品失败");
        // 设置热键
        webSocketUtil.setHotKey();
        // 关闭连接
        webSocketUtil.closeConnect();
        return conncetStr;
    }
}
